package common.utils.htk;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;

import common.utils.GetAllFilesOfDir;

/**
 * A partir de los archivos wav, genera los archivos que contienen los 
 * coeficientes de mfcc de los wav indicados, utilizando htk
 * @author Martin
 *
 */
public class FromWavToMfccCoef {
	
	private static final String LOG4J = "log4jWavMfcc.properties";
	
	private static final Logger  logger  = Logger.getLogger(FromWavToMfccCoef.class);
	
	static SimpleDateFormat format = new SimpleDateFormat ("dd/MM/yyyy hh:mm:ss");
	

	
	public FromWavToMfccCoef(){
		PropertyConfigurator.configure(LOG4J);
		logger.info("**********************************************************************************************");
		Date date=new Date();
		
		logger.info("Comienza "+format.format(date));

	}
	
	private static void inicialicePaths(String[] pathsWavsArchivos,String[] pathsDestinoArchivos){
		String pathArchivos="D:\\WAVS_TO_COEF\\Naty\\Prueba3\\";

		pathsWavsArchivos[0]=pathArchivos+"wavFiles\\luz";
		pathsWavsArchivos[1]=pathArchivos+"wavFiles\\otros";
		pathsWavsArchivos[2]=pathArchivos+"wavFiles\\persiana";
		pathsWavsArchivos[3]=pathArchivos+"wavFiles\\radio";
		pathsWavsArchivos[4]=pathArchivos+"wavFiles\\cerrar";
		pathsWavsArchivos[5]=pathArchivos+"wavFiles\\video";
		pathsWavsArchivos[6]=pathArchivos+"wavFiles\\tv";


		pathsDestinoArchivos[0]=pathArchivos+"mfccTextCoef\\luz";
		pathsDestinoArchivos[1]=pathArchivos+"mfccTextCoef\\otros";
		pathsDestinoArchivos[2]=pathArchivos+"mfccTextCoef\\persiana";
		pathsDestinoArchivos[3]=pathArchivos+"mfccTextCoef\\radio";
		pathsDestinoArchivos[4]=pathArchivos+"mfccTextCoef\\cerrar";
		pathsDestinoArchivos[5]=pathArchivos+"mfccTextCoef\\video";
		pathsDestinoArchivos[6]=pathArchivos+"mfccTextCoef\\tv";
		
	}
	
	
	public void transformarTodos(String[] pathsWavsArchivos, String[] pathsDestinoArchivos ){


		String pathWavFile;
		String pathDestFile;
	
		for (int i=0;i<7;i++){

			pathWavFile = pathsWavsArchivos[i];
			pathDestFile = pathsDestinoArchivos[i];
			
			//recorro todos los archivos de la carpeta de wav y creo los correspondientes en la carpeta de Dest
			GetAllFilesOfDir g=new GetAllFilesOfDir();
			List<File> lista=new ArrayList<File>();
			lista.addAll(g.getListNameOfFilesInDir(pathWavFile));
			
			//lleno las matrices con los valores normalizados
			for (File file: lista){
			
				System.out.println("De "+file.getAbsolutePath());
				logger.info("Path del wav "+file.getAbsolutePath());

				String fileName=file.getName().substring(0, file.getName().length()-4);
				logger.info("Path del destino "+pathDestFile+"\\"+fileName+".txt");
				transformar(file.getAbsolutePath(),pathDestFile+"\\"+fileName+".txt");
				
			}

			
		}
		
						
	}
	
	private void transformar(String pathWav, String pathDestCoef){

		String pathHTK="C:\\cygwin\\HTK\\htk-3.3-windows-binary\\htk\\";
		//Hlist -C config -h -t -o -i 39 luzWav\\coefmfcc\\luz-01.txt > luzWav\\coefmfcctexto\\aseg-01.txt

		String cmd=pathHTK+"HList";

		String pathConfigFile = "C:\\Recognizer\\test\\config";
		        		
		File arch=new File(pathConfigFile);
		if (!arch.exists()){
			System.out.println("No existe el archivo de configuracion para ejecutar HCopy, en el directorio "+pathConfigFile);
			System.out.println("esto puede provacar el fracaso del reconocimiento");
		}
		else {
			cmd+=" -C "+pathConfigFile;
		}

		cmd+=" -h -t -o -i 39 "+pathWav;//+" > "+pathDestCoef;
				
		List<String> resultadoString = executeCommand(cmd);	
		
		//genero el archivo de salida con el string que recibi 
		File file = new File(pathDestCoef);
		if (!file.exists()){
			try {
				file.createNewFile();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		PrintWriter writer;
		try {
			
			writer = new PrintWriter(file);
			Iterator<String> iterator= resultadoString.iterator();
			while (iterator.hasNext())
				writer.print(iterator.next()+"\n");
			
			writer.close();
		
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	
	}

	
	private List<String> executeCommand(String cmd) {
		Process pr;
		BufferedReader input;
		String line;
		Runtime rt=Runtime.getRuntime();
		logger.info("Ejecutando comando: "+cmd);
		logger.info("Resultado: ");
        String[] msg = {"", ""};
        line = null;

        List<String> resultado = new ArrayList<String>();
        try {
            // execute command
            pr = rt.exec(cmd);

            // read message from console
            input = new BufferedReader(new InputStreamReader(pr.getInputStream()));
            while ((line = input.readLine()) != null) {
                msg[0] = msg[0] + "\t" + line + "\n";
                logger.info(line);
                resultado.add(line);
            }

            System.out.println("Resultado:\n"+msg[0]);
            
            // read error message
            input = new BufferedReader(new InputStreamReader(pr.getErrorStream()));
            while ((line = input.readLine()) != null) {
                msg[1] = msg[1] + "\t" + line + "\n";
            }
            if (msg[1].length() > 1) {
                try {
                	System.out.println("Exepcion\n");
					throw new Exception("\t" + cmd + "\n" + msg[0] + "\n" + msg[1]);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
            }
            System.out.println( "Executed command: \"" + cmd + "\"\n");
            
        } catch (IOException ex) {
            try {
				throw new IOException("Error while executing cmd: " + cmd + "\n" + msg[0] + "\n" + msg[1], ex);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
        }

        return resultado;
		
	}

	
	public static void main(String[] args) {
		System.out.println();

		FromWavToMfccCoef fromWavToMfccCoef= new FromWavToMfccCoef();
		
		String[] pathsWavsArchivos = new String[7];
		String[] pathsDestinoArchivos = new String[7];
		inicialicePaths(pathsWavsArchivos,pathsDestinoArchivos);

		fromWavToMfccCoef.transformarTodos(pathsWavsArchivos,pathsDestinoArchivos);
		
		logger.info("**************************FIN");
		
    }
	
	
}
